{"componentChunkName":"component---src-templates-post-js","path":"/simply-learn-full-stack-3","result":{"data":{"site":{"siteMetadata":{"title":"neohed","description":"Blog posts on web development and related areas","author":{"name":"neohed"},"keywords":["Web Development","JavaScript"]}},"mdx":{"frontmatter":{"title":"Simply Learn Full-Stack Web, Part 3","description":"Tutorial to learn full-stack with React node.js and Prisma DB","date":"June 27, 2022","author":null,"banner":null,"slug":"simply-learn-full-stack-3","keywords":null},"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"slug\": \"simply-learn-full-stack-3\",\n  \"date\": \"2022-06-27T08:36:32\",\n  \"title\": \"Simply Learn Full-Stack Web, Part 3\",\n  \"description\": \"Tutorial to learn full-stack with React node.js and Prisma DB\",\n  \"published\": true\n};\n\nvar makeShortcode = function makeShortcode(name) {\n  return function MDXDefaultShortcode(props) {\n    console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n    return mdx(\"div\", props);\n  };\n};\n\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"h1\", null, \"Simply Learn Full-Stack React & Node.js\"), mdx(\"p\", null, \"First create a folder \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"node-server\"), \" at the same level as folder \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"react-client\")), mdx(\"p\", null, \"Inside the \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"node-server\"), \" folder, use a shell/CLI to enter this command to create a \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"package.json\"), \" file:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-shell\"\n  }), \"npm init -y\\n\")), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"-y\"), \" flag means that \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"package.json\"), \" will be filled with defaults. You can edit the file later to add your name and repository details, etc.\")), mdx(\"p\", null, \"Next run this to install some dependencies:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-shell\"\n  }), \"npm i -S express body-parser cors morgan\\n\")), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"i\"), \" is shorthand for \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"install\"), \"\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"-S\"), \" is shorthand for \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"-save\"))), mdx(\"p\", null, \"Create \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"index.js\"), \" and paste in this code:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const express = require('express');\\nconst cors = require('cors');\\nconst morganLogger = require('morgan');\\nconst bodyParser = require('body-parser');\\n\\nconst env = process.env.NODE_ENV || 'development';\\nconst app = express();\\n\\nif (env === 'development') {\\n  app.use(cors());\\n}\\n\\napp.use(morganLogger('dev'));\\napp.use(bodyParser.json());\\napp.use(bodyParser.urlencoded({extended: true}));\\n\\n// 404 route not found!\\napp.use(function (req, res, next) {\\n  const error = 'Here be dragons. Route not found';\\n  console.info(`404 error! ${error}`)\\n  res.status(404).send(error);\\n});\\n\\nconst port = 4011;\\n\\napp.listen({port}, async () => {\\n  const baseUrl = `http://localhost:${port}`;\\n\\n  console.log(`Server running at: \\\\t @ ${baseUrl}/`);\\n});\\n\")), mdx(\"p\", null, \"I will briefly explain the packages we are importing.\"), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"express\"), \" is the web framework.\"), mdx(\"p\", null, \"The \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"cors\"), \" package disables \\\"cross origin resource sharing\\\", where origin is a URL and resources are assets like images. The purpose of the \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"cors\"), \" policy is to prevent a website from pointing their image links to a different site and stealing hosting costs. In development we allow cors because we run both the React client and the Node server on one machine, each in their own process (live you could deploy both to the same folder and avoid cors issues). The port numbers on the server and client URL's are needed so the traffic (HTTP requests and responses) can be sent to the correct process. Port numbers are included in the browser decision on the \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"origin\"), \" of the server response\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"Your browser sees the website is on port 3000 but it attempts to fetch data from port 4011.  Even though they both run on localhost, because the port numbers are different, to a browser they are different websites entirely! If we didn't disable cors, this request would violate the \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"same-origin\"), \" policy and be denied!\")), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"body-parser\"), \" is middleware that parses incoming requests to extract data for us, in this case json (it also includes a few other parsers that can be useful).\"), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"morgan\"), \" is a middleware request logger. In this case we pipe all messages to the console (you could instead write to a file). This is one of the most essential things to include in any node server. For troubleshooting and debugging, seeing all requests logged to your console is pure gold!\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"You might notice our server returns no data, has no routes defined, but has a 404 handler. I always add a 404 handler first! When your app grows and has complex routing, getting a clear message, a \\\"final destination\\\" for unmatched routes is essential for development and debugging.\")), mdx(\"p\", null, \"Next edit \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"package.json\"), \", and change the \\\"scripts\\\" section to add an additional line:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-json\"\n  }), \"  \\\"scripts\\\": {\\n    \\\"start\\\": \\\"node index.js\\\",\\n    \\\"test\\\": \\\"echo \\\\\\\"Error: no test specified\\\\\\\" && exit 1\\\"\\n  },\\n\")), mdx(\"p\", null, \"Finally, you should be able to run your Node.js server with this command:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-shell\"\n  }), \"npm run start\\n\")), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"Run this in the same folder as the \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"package.json\"), \" file\")), mdx(\"p\", null, \"When the console outputs a message saying the server is running, paste this URL into a browser: \\\"\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"http://localhost:4011/\"\n  }), \"http://localhost:4011/\"), \"\\\"\"), mdx(\"p\", null, \"You should see a text message: \\\"Here be dragons. Route not found\\\"\"), mdx(\"p\", null, \"This is good. We received an HTTP 404 error, which is what we expect as, currently, our server returns no data and has no routing paths defined.\"), mdx(\"p\", null, \"You now have a working client and server. \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/simply-learn-full-stack-4\"\n  }), \"Next we will return some data\"), \".\"), mdx(\"p\", null, \"Code repo: \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/neohed/node-react-stack\"\n  }), \"Github Repository\")));\n}\n;\nMDXContent.isMDXComponent = true;"}},"pageContext":{"id":"2390e060-6276-55f3-89cf-91f581fdf491","prev":{"id":"2dec4ce8-7bf3-555d-80f7-a06fd8cce40b","parent":{"name":"index","sourceInstanceName":"blog"},"excerpt":"Simply Learn Full-Stack React & Node.js Inside folder  node-server , create a new folder called \"controllers.\"  Inside add a file called  note.controller.js  and add the following code: Why  .controller.js ? In a complex app, you will have many…","fields":{"title":"Full-Stack React & Node.js, Part 4 - Get data from server","description":"Tutorial to learn full-stack with React node.js and Prisma DB","slug":"simply-learn-full-stack-4","absolutePath":"D:/Workspace/Github/neohed-blog/content/blog/learn-full-stack-simply-04/index.mdx","banner":null,"date":"2022-06-27T08:36:32"}},"next":{"id":"d50e9e7d-2aa1-5ec2-bf62-2070f5612432","parent":{"name":"index","sourceInstanceName":"blog"},"excerpt":"Simply Learn Full-Stack React & Node.js Finally, the fun part is here! All our components are in place and now we only need to change 1 component to get the server and client talking. In  react-client , edit  AddEditNote.js , and replace the contents…","fields":{"title":"Full-Stack React & Node.js, Part 5 - Get client & server talking","description":"Tutorial to learn full-stack with React node.js and Prisma DB","slug":"simply-learn-full-stack-5","absolutePath":"D:/Workspace/Github/neohed-blog/content/blog/learn-full-stack-simply-05/index.mdx","banner":null,"date":"2022-06-27T08:36:32"}}}}}